package com.aizuda.boot.modules.third.wps.service;

import com.aizuda.boot.modules.common.constant.RedisKeyConstant;
import com.aizuda.boot.modules.common.util.RedisService;
import com.aizuda.boot.modules.file.domain.entity.FileInfo;
import com.aizuda.boot.modules.file.service.FileInfoService;
import com.aizuda.boot.modules.third.wps.domain.dto.XUserQuery;
import com.aizuda.boot.modules.third.wps.domain.entity.FileHistory;
import com.aizuda.boot.modules.third.wps.domain.vo.FileDownloadVo;
import com.aizuda.boot.modules.third.wps.domain.vo.FileInfoVo;
import com.aizuda.boot.modules.third.wps.domain.vo.FilePermissionVo;
import com.aizuda.boot.modules.third.wps.enums.WebOfficeErrEnum;
import com.aizuda.boot.modules.third.wps.exception.WebOfficeException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

/**
 * @author hjw
 * @description WPS weboffice Service处理
 * @date 2025年06月13日 18:14
 */
@Service
public class PreviewService {


    @Value("${file.storage.local.download-url-prefix}")
    private String downloadUrlPrefix;


    @Autowired
    private FileHistoryService fileHistoryService;

    @Autowired
    private FileInfoService fileInfoService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private WebOfficeInterface webOfficeInterface;


    /**
     * 获取预览文件信息
     *
     * @param fileId 文件 ID
     * @return PreviewFileInfoVo
     */
    public FileInfoVo getPreviewFileInfo(String fileId) {

        // 根据 fileId 获取原始文件信息
        FileInfo fileInfo = fileInfoService.lambdaQuery()
                .eq(FileInfo::getFileId, fileId)
                .one();

        if (fileInfo == null) {
            throw new WebOfficeException(WebOfficeErrEnum.FILE_NOT_FOUND);
        }
        String lockKey = RedisKeyConstant.LockKeyPrefix.WEB_OFFICE_FILE_PREVIEW + fileId;

        try {
            //获取锁
            boolean lock = redisService.tryLock(lockKey);
            if (!lock) {
                throw new WebOfficeException(WebOfficeErrEnum.SYSTEM_ERROR);
            }

            FileHistory fileHistory = fileHistoryService.lambdaQuery()
                    .eq(FileHistory::getFileId, fileId)
                    .isNotNull(FileHistory::getVersion)
                    .orderByDesc(FileHistory::getVersion)
                    .last("limit 1")
                    .one();

            FileInfoVo fileInfoVo;
            if (fileHistory != null) {
                fileInfoVo = FileInfoVo.builder()
                        .id(fileHistory.getFileId().toString())
                        .name(fileHistory.getFileName())
                        .version(fileHistory.getVersion())
                        .size(fileHistory.getFileSize())
                        .createTime(fileHistory.getCreateTime().toInstant().getEpochSecond())
                        .modifyTime(fileHistory.getModifyTime().toInstant().getEpochSecond())
                        .creatorId(fileHistory.getCreatorId())
                        .modifierId(fileHistory.getModifierId())
                        .build();
            } else {
                fileInfoVo = FileInfoVo.builder()
                        .id(fileInfo.getFileId().toString())
                        .name(fileInfo.getFileName())
                        .version(1)
                        .size(fileInfo.getFileSize())
                        .createTime(fileInfo.getCreateTime().toInstant().getEpochSecond())
                        .modifyTime(fileInfo.getCreateTime().toInstant().getEpochSecond())
                        .creatorId(fileInfo.getCreatorId() == null ? null : fileInfo.getCreatorId().toString())
                        .modifierId(fileInfo.getCreatorId() == null ? null : fileInfo.getCreatorId().toString())
                        .build();
                //    将原始文件信息第一版记录保存到 history表
                fileHistoryService.save(FileHistory.builder()
                        .fileId(Long.valueOf(fileId))
                        .version(1)
                        .fileName(fileInfo.getFileName())
                        .fileSize(fileInfo.getFileSize())
                        .fileKey(fileInfo.getFileKey())
                        .creatorId(fileInfo.getCreatorId().toString())
                        .createTime(fileInfo.getCreateTime())
                        .modifierId(fileInfo.getCreatorId().toString())
                        .modifyTime(fileInfo.getCreateTime())
                        .build()
                );

            }
            return fileInfoVo;
        } finally {
            //释放锁
            redisService.unlock(lockKey);
            redisService.clearThreadLockContext();
        }

    }

    /**
     * 获取文件下载地址
     *
     * @param fileId 文件 ID
     * @return String 下载地址
     */
    public FileDownloadVo getFileDownloadUrl(String fileId) {
        // 根据 fileId 获取原始文件信息
        FileInfo fileInfo = fileInfoService.lambdaQuery()
                .eq(FileInfo::getFileId, fileId)
                .one();

        if (fileInfo == null) {
            throw new WebOfficeException(WebOfficeErrEnum.FILE_NOT_FOUND);
        }

        FileHistory fileHistory = fileHistoryService.lambdaQuery()
                .eq(FileHistory::getFileId, fileId)
                .isNotNull(FileHistory::getVersion)
                .orderByDesc(FileHistory::getVersion)
                .last("limit 1")
                .one();

        String fileKey;
        if (fileHistory != null) {
            fileKey = fileHistory.getFileKey();
        } else {
            fileKey = fileInfo.getFileKey();
        }
        return FileDownloadVo.builder()
                .url(downloadUrlPrefix + "?fileKey=" + fileKey)
                .build();

    }

    /**
     * 获取文件权限
     *
     * @param param 参数信息
     * @return FilePermissionVo 文件权限信息
     */
    public FilePermissionVo getFilePermission(XUserQuery param, String userId) {
        //todo 根据 fileId 获取文件的权限信息,暂时返回全部权限

        return webOfficeInterface.getFilePermission(param, userId);
    }

    //  根据文件id校验文件
    public void validateFileId(String fileId) {
        // 根据 fileId 查询文件信息
        FileInfo fileInfo = fileInfoService.lambdaQuery()
                .eq(FileInfo::getFileId, fileId)
                .one();
        // 如果文件信息不存在，抛出异常
        if (fileInfo == null) {
            throw new WebOfficeException(WebOfficeErrEnum.FILE_NOT_FOUND);
        }

        //todo 根据 fileId 校验文件是否存在 根据不同的场景返回不同的异常信息(抛出异常或返回错误码)

    }

}
